package org.example.config;

import org.example.mapper.ScheduleTaskMapper;
import org.example.scheduledEntity.ScheduSpringCron;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;

@Configuration
public class ScheduleConfig implements SchedulingConfigurer {

    @Autowired
    private  ApplicationContext  applicationContext;

    @Resource
    private ScheduleTaskMapper  scheduleTaskMapper;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

            for (ScheduSpringCron cron:scheduleTaskMapper.getScheduleTaskList()){
                Class<?> clazz;

                Object task;

                try {
                    clazz=Class.forName(cron.getCronKey());

                    task=applicationContext.getBean(clazz);

                }catch (ClassNotFoundException e){
                    throw  new IllegalArgumentException("schedule_spring_cron的表数据："+cron.getCronKey()+"有误",e);
                }catch (BeansException e){
                    throw  new IllegalArgumentException(cron.getCronKey()+"未注入到spring到spring容器中",e);
                }
                //Assert.isAssignable(ScheduledTask.class,task.getClass(),"定时任务类必须实现该接口");

                //通过改变数据库数据去实现动态改变执行周期
                taskRegistrar.addTriggerTask((Runnable) task,triggerContext->{
                    String cronExpression = scheduleTaskMapper.getScheduleTaskByCronKey(cron.getCronKey()).getCronExpression();
                    return  new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
                });
            }
    }


    @Bean
    public Executor  taskExecutor(){
        return Executors.newScheduledThreadPool(10);
    }

}
